/*
 * @Description: 用户相关的工具类
 * @Author: chenju
 * @Date: 2021-11-11 17:17:16
 * @LastEditors: chenju
 * @LastEditTime: 2022-10-12 17:59:00
 */

import { store } from '@/store';
import { UserMutationTypes } from '@/store/modules/user/mutation-types';

// menu接口返回值
// item
export interface MenuResItem {
  id: number;
  parentId: number;
  // 菜单名称
  label: string;
  // 菜单icon
  icon: null | string;
  // 菜单name
  name: null | string;
  // 菜单路径
  path: null | string;
  // permission的key
  permission: string;
  // 菜单类型
  // '0' 菜单
  // '1' 按钮
  type: '0' | '1';
  spread: null | string;
  component: null | string;
  keepAlive: string;
  sort: number;
  children: null | MenuResItem[];
}
export type MenuResType = MenuResItem[];

// menu需要的格式
// item
export interface MenuTree {
  id: number;
  parentId: number;
  label: string;
  name?: string;
  path: string;
  icon?: string;
  redirect?: string;
  children: null | MenuTree[];
}
export type MenuTreeType = MenuTree[];

export interface MenuListItem {
  id: number;
  parentId: number;
  label: string;
  path: string;
  icon?: string;
  redirect?: string;
}

export type MenuList = MenuListItem[];

// 获取菜单tree
export const getMenuTree = (menuRes: MenuResType): MenuTreeType => {
  // 按钮权限
  const permissions: string[] = [];
  const topMenus: any[] = [];
  for (let i = 0; i < menuRes.length; i++) {
    const item = menuRes[i];
    topMenus.push(item);
  }
  // 获取菜单tree
  const menuTree = getMenuTreeRecursion(menuRes, permissions);
  console.log('menu', menuTree);
  // 获取菜单列表
  const menuList: MenuList = getMenuListRecursion(menuTree);
  console.log('menu-list', menuList);

  // 设置菜单列表store
  store.commit(UserMutationTypes.SET_TOPMENUS, topMenus);
  store.commit(UserMutationTypes.SET_MENU_TREE, menuTree);
  store.commit(UserMutationTypes.SET_MENU_LIST, menuList);
  return menuTree;
  // // 首页菜单
  // const homeMenu = {
  //   id: 0,
  //   parentId: -1,
  //   label: '首页',
  //   path: '/background/home',
  //   children: null
  // };
  // return [homeMenu, ...menuTree];
};

// 使用递归获取菜单tree
export const getMenuTreeRecursion = (menuRes: MenuResType, permissions: string[]): MenuTreeType => {
  if (!menuRes || !menuRes.length) return [];
  const ans: MenuTreeType = [];
  for (const i in menuRes) {
    const item: MenuResItem = menuRes[i];
    // 按钮权限
    if (item.type === '1') permissions.push(item.permission);
    else {
      const children = item.children ? getMenuTreeRecursion(item.children, permissions) : null;
      const menuTree = {
        id: item.id,
        parentId: item.parentId,
        label: item.label || '',
        name: item.name || '',
        path: item.path || '',
        icon: item.icon || '',
        children: children && children.length ? children : null
      };
      // 重定向
      if (item.parentId === -1) {
        const redirect = getRedirectUrl(item);
        Object.assign(menuTree, {
          redirect: redirect && redirect?.indexOf('/') !== 0 ? `/${redirect}` : redirect
        });
      }
      ans.push(menuTree);
    }
  }
  return ans;
};

// 获取重定向地址（打开顶部menu时重定向到第一个菜单）
const getRedirectUrl = (item: MenuResItem): string => {
  let localItem = JSON.parse(JSON.stringify(item));
  while (
    localItem.type === '0' &&
    localItem.children &&
    localItem.children.length &&
    localItem.children[0].type === '0'
  ) {
    localItem = localItem.children[0];
  }
  console.log('localItem', localItem);
  return localItem.path;
};

// 获取菜单列表 二维的
const getMenuListRecursion = (menuTree: MenuTree[]): MenuList => {
  if (!menuTree || !menuTree.length) return [];
  let ans: MenuList = [];
  for (let i = 0, menuLength = menuTree.length; i < menuLength; i++) {
    const item: MenuTree = menuTree[i];
    const menuListItem = {
      id: item.id,
      parentId: item.parentId,
      label: item.label || '',
      path: item.path || '',
      icon: item.icon || '',
      redirect: item.redirect
    };
    ans.push(menuListItem);
    if (item.children && item.children.length) {
      const childrenAns = getMenuListRecursion(item.children);
      ans = ans.concat(childrenAns);
    }
  }
  return ans;
};
